﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace team33_ass3
{
    class Chest : GameObject
    {
        Player goal;
        AStar aStar;
        Vector3 waypoint;
        Vector3 destination;
        List<MapBlock> path;
        Map map;
        public Chest(Model model, Vector3 pos, Player player, AStar aStar, Map map)
            : base(model, pos)
        {
            this.goal = player;
            scaleValue = 0.05f;
            this.map = map;
            this.aStar = aStar;
            setDestination();
            getNewWayPoint();
        }

        public void Update(GameTime gameTime)
        {
            if (atWayPoint())
            {
                float speed = 0.07f;
                Vector3 direction = waypoint - this.position;
                direction.Normalize();
                double time = gameTime.ElapsedGameTime.TotalMilliseconds;

                float distanceFromGoal = Vector3.Distance(goal.position, this.position);

                if (distanceFromGoal < 200f)
                {
                    if (this.position != goal.position)
                    {
                        this.position += (direction * speed * (float)time);
                    }
                }
            }
            // at the waypoint, need new waypoint
            else
            {
                getNewWayPoint();
            }
        }

        private void getNewWayPoint()
        {
            path = aStar.getPath(this.position, destination);
            if (path.Count > 0)
            {
                MapBlock tmp = path.ElementAt(0);
                waypoint = new Vector3(tmp.getRealX(), 0, tmp.getRealY());
            }
        }

        private bool atWayPoint()
        {
            return (map.getBlock(this.position) != map.getBlock(waypoint)) && closeEnough();
        }

        private bool closeEnough()
        {
            float x = Math.Abs(this.position.X - waypoint.X);
            float y = Math.Abs(this.position.Z - waypoint.Z);

            return !(x == 0 && y == 0);
        }

        private void setDestination()
        {
            List<MapBlock> randomList = new List<MapBlock>();

            foreach (MapBlock mp in map.walkables)
            {
                randomList.Add(mp);
            }

            randomList = Map.Randomize<MapBlock>(randomList);

            foreach (MapBlock mp in randomList)
            {
                int estimate = AStar.estimateScore(map.getBlock(goal.position), mp);
                if (estimate >= 6 && estimate <= 15)
                {
                    destination = new Vector3(mp.getRealX(), 0f, mp.getRealY());

                    break;
                }
            }
        }
    }
}
